#include "AsyncClient.hpp"
#include "ESPAsyncWebServer.h"
#include "WebHandlerImpl.h"
#include "esp_log.h"

#define TAG "WebServer"

AsyncWebServer::AsyncWebServer(uint16_t port)
    : m_server(port)
    , m_rewrites(LinkedList<AsyncWebRewrite*>([](AsyncWebRewrite * r)
{
    delete r;
}))
, m_handlers(LinkedList<AsyncWebHandler*>([](AsyncWebHandler*h)
{
    delete h;
}))
{
    m_catchAllHandler = new AsyncCallbackWebHandler();
    if (m_catchAllHandler == nullptr) {
        ESP_LOGE(TAG, "未定义通用处理器!");
        return;
    }
    m_server.set_connected_handler([](void* s, AsyncClient * client) {
        if (client == nullptr) {
            return;
        }
        client->set_rx_timeout_second(3);
        auto* req = new AsyncWebServerRequest((AsyncWebServer*)s, client);
        if (req == nullptr) {
            client->close(true);
            // client->free();
            // delete client;
        }
    },
    this
                                  );
}

AsyncWebServer::~AsyncWebServer()
{
    reset();
    end();
    if (m_catchAllHandler != nullptr) {
        delete m_catchAllHandler;
    }
}

/// @brief 添加一个URL重写规则
/// @param rewrite
/// @return
AsyncWebRewrite &AsyncWebServer::addRewrite(AsyncWebRewrite* rewrite)
{
    m_rewrites.add(rewrite);
    return* rewrite;
}

/// @brief 移除一个URL重写规则
bool AsyncWebServer::removeRewrite(AsyncWebRewrite* rewrite)
{
    return m_rewrites.remove(rewrite);
}

/// @brief 添加一个重写规则
AsyncWebRewrite &AsyncWebServer::rewrite(const char* from, const char* to)
{
    return addRewrite(new AsyncWebRewrite(from, to));
}

/// @brief 添加一个请求处理器
AsyncWebHandler &AsyncWebServer::addHandler(AsyncWebHandler* handler)
{
    m_handlers.add(handler);
    return *handler;
}

/// @brief 移除一个请求处理器
bool AsyncWebServer::removeHandler(AsyncWebHandler* handler)
{
    return m_handlers.remove(handler);
}

/// @brief 启动服务器，开始监听
void AsyncWebServer::begin()
{
    m_server.set_nodelay(true);
    m_server.begin();
}

/// @brief 停止服务器，关闭连接
void AsyncWebServer::end()
{
    m_server.end();
}

/// @brief 处理客户端断开连接的情况
void AsyncWebServer::_handleDisconnect(AsyncWebServerRequest* req)
{
    if (req != nullptr) {
        delete req;
        req = nullptr;
    }
}

/// @brief 对匹配重写规则的请求进行重写
void AsyncWebServer::_rewriteRequest(AsyncWebServerRequest* req)
{
    for (const auto &r : m_rewrites) {
        if (r->match(req)) {
            req->m_url = r->toUrl();
            req->m_addGetParams(r->params());
            ESP_LOGI(TAG, "重写请求");
        }
    }
}

/// @brief 根据请求过滤器绑定合适的处理器
void AsyncWebServer::_attachHandler(AsyncWebServerRequest* req)
{
    for (const auto &h : m_handlers) {
        if (h->filter(req) && h->canHandle(req)) {
            req->setHandler(h);
            return;
        }
    }
    req->addInterestingHeader("ANY");
    req->setHandler(m_catchAllHandler);
}

/// @brief 设置指定URI的响应回调函数
AsyncCallbackWebHandler &AsyncWebServer::on(const char* uri, ArRequestHandlerFunction onRequest)
{
    auto* handler = new AsyncCallbackWebHandler();
    handler->setUri(uri);
    handler->onRequest(onRequest);
    addHandler(handler);
    return *handler;
}

/// @brief 设置指定URI、方法的响应回调函数
AsyncCallbackWebHandler &AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest)
{
    auto* handler = new AsyncCallbackWebHandler();
    handler->setUri(uri);
    handler->setMethod(method);
    handler->onRequest(onRequest);
    addHandler(handler);
    return *handler;
}

/// @brief 设置指定URI、方法的处理函数
AsyncCallbackWebHandler &AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload)
{
    auto* handler = new AsyncCallbackWebHandler();
    handler->setUri(uri);
    handler->setMethod(method);
    handler->onRequest(onRequest);
    handler->onUpload(onUpload);
    addHandler(handler);
    return *handler;
}

AsyncCallbackWebHandler &AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody)
{
    auto* handler = new AsyncCallbackWebHandler();
    handler->setUri(uri);
    handler->setMethod(method);
    handler->onRequest(onRequest);
    handler->onUpload(onUpload);
    handler->onBody(onBody);
    addHandler(handler);
    return *handler;
}

/// @brief 设置指定URI的静态文件服务
/// @param uri 访问的URI路径
/// @param path 静态文件基础路径
/// @param cache_control 缓存控制字段
AsyncStaticWebHandler &AsyncWebServer::serveStatic(const char* uri, const char* path, const char* cache_control)
{
    auto* handler = new AsyncStaticWebHandler(uri, path, cache_control);
    addHandler(handler);
    return *handler;
}

/// @brief 设置当没有找到对应处理器时调用的回调函数
void AsyncWebServer::onNotFound(ArRequestHandlerFunction fn)
{
    m_catchAllHandler->onRequest(fn);
}

/// @brief 处理文件上传事件
void AsyncWebServer::onFileUpload(ArUploadHandlerFunction fn)
{
    m_catchAllHandler->onUpload(fn);
}

/// @brief 处理带有“请求主体”的POST请求
void AsyncWebServer::onRequestBody(ArBodyHandlerFunction fn)
{
    m_catchAllHandler->onBody(fn);
}

/// @brief 重置服务器（清除所有处理器和重写规则）
void AsyncWebServer::reset()
{
    m_rewrites.free();
    m_handlers.free();

    if (m_catchAllHandler != nullptr) {
        m_catchAllHandler->onRequest(nullptr);
        m_catchAllHandler->onUpload(nullptr);
        m_catchAllHandler->onBody(nullptr);
    }
}